#include "../include/GLUTFunctions.h"

int subwindow_width;
int subwindow_height;
int subwindow_x;
int subwindow_y;
int window_width;
int window_height;
int old_window_width;
int old_window_height;
int	main_window;

void GLUTInit(int argc, char** argv) 
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH | WS_OVERLAPPED);
	glutInitWindowSize(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
	glutInitWindowPosition(DEFAULT_WINDOW_POS_X, DEFAULT_WINDOW_POS_Y);
	main_window = glutCreateWindow("CS6360 Assignment 1");
	glutDisplayFunc(myGlutDisplay);
}

void myGlutIdle(void)
{
	// make sure the main window is active
	if (glutGetWindow() != main_window)
		glutSetWindow(main_window);

	//re-synchronize all the live variables
	glui->sync_live();



	// just keep redrawing the scene over and over
	glutPostRedisplay();


}

// mouse handling functions for the main window
// left mouse translates, middle zooms, right rotates
// keep track of which button is down and where the last position was
int cur_button = -1;
int last_x;
int last_y;

// catch mouse up/down events
void myGlutMouse(int button, int state, int x, int y)
{
	if(state == GLUT_DOWN) {
		last_x = x;
		last_y = y;
	}

}



// catch mouse move events
void myGlutMotion(int x, int y)
{
	/*// the change in mouse position
	int dx = x-last_x;
	int dy = y-last_y;


	float scale, len, theta;
	float neye[3], neye2[3];
	float f[3], r[3], u[3];
	//in normal mode
	switch(cur_button)
	{
	case GLUT_LEFT_BUTTON:
	// translate
	f[0] = lookat[0] - eye[0];
	f[1] = lookat[1] - eye[1];
	f[2] = lookat[2] - eye[2];
	u[0] = 0;
	u[1] = 1;
	u[2] = 0;

	// scale the change by how far away we are
	scale = sqrt(length(f)) * 0.007;

	crossproduct(f, u, r);
	crossproduct(r, f, u);
	normalize(r);
	normalize(u);

	eye[0] += -r[0]*dx*scale + u[0]*dy*scale;
	eye[1] += -r[1]*dx*scale + u[1]*dy*scale;
	eye[2] += -r[2]*dx*scale + u[2]*dy*scale;

	lookat[0] += -r[0]*dx*scale + u[0]*dy*scale;
	lookat[1] += -r[1]*dx*scale + u[1]*dy*scale;
	lookat[2] += -r[2]*dx*scale + u[2]*dy*scale;

	break;

	case GLUT_MIDDLE_BUTTON:
	// zoom
	f[0] = lookat[0] - eye[0];
	f[1] = lookat[1] - eye[1];
	f[2] = lookat[2] - eye[2];

	len = length(f);
	normalize(f);

	// scale the change by how far away we are
	len -= sqrt(len)*dx*0.03;

	eye[0] = lookat[0] - len*f[0];
	eye[1] = lookat[1] - len*f[1];
	eye[2] = lookat[2] - len*f[2];

	// make sure the eye and lookat points are sufficiently far away
	// push the lookat point forward if it is too close
	if (len < 1)
	{
	printf("lookat move: %f\n", len);
	lookat[0] = eye[0] + f[0];
	lookat[1] = eye[1] + f[1];
	lookat[2] = eye[2] + f[2];
	}

	break;

	case GLUT_RIGHT_BUTTON:
	// rotate

	neye[0] = eye[0] - lookat[0];
	neye[1] = eye[1] - lookat[1];
	neye[2] = eye[2] - lookat[2];

	// first rotate in the x/z plane
	theta = -dx * 0.007;
	neye2[0] = (float)cos(theta)*neye[0] + (float)sin(theta)*neye[2];
	neye2[1] = neye[1];
	neye2[2] =-(float)sin(theta)*neye[0] + (float)cos(theta)*neye[2];


	// now rotate vertically
	theta = -dy * 0.007;

	f[0] = -neye2[0];
	f[1] = -neye2[1];
	f[2] = -neye2[2];
	u[0] = 0;
	u[1] = 1;
	u[2] = 0;
	crossproduct(f, u, r);
	crossproduct(r, f, u);
	len = length(f);
	normalize(f);
	normalize(u);

	neye[0] = len * ((float)cos(theta)*f[0] + (float)sin(theta)*u[0]);
	neye[1] = len * ((float)cos(theta)*f[1] + (float)sin(theta)*u[1]);
	neye[2] = len * ((float)cos(theta)*f[2] + (float)sin(theta)*u[2]);

	eye[0] = lookat[0] - neye[0];
	eye[1] = lookat[1] - neye[1];
	eye[2] = lookat[2] - neye[2];

	//printf("Eye: %f %f %f\n", eye[0], eye[1], eye[2]);
	//printf("Lookat: %f %f %f\n", lookat[0], lookat[1], lookat[2]);
	break;
	}



	last_x = x;
	last_y = y;


	//render_to_env_map();
	glutPostRedisplay();
	*/
}

// you can put keyboard shortcuts in here
void myGlutKeyboard(unsigned char key, int x, int y)
{
	switch(key)
	{
		// quit
	case 27: 
	case 'q':
	case 'Q':
		break;
	case 'f':
		ToggleFullScreen();
		break;
	case 's':
		stereo_view->set_int_val(!stereo_view->get_int_val());
		break;
	case 'o':
		draw_object->set_int_val(!draw_object->get_int_val());
		break;
	case 'l':
		draw_floor->set_int_val(!draw_floor->get_int_val());
		break;
	}

	glutPostRedisplay();
}

// the window has changed shapes, fix ourselves up
void myGlutReshape(int	x, int y)
{
	window_width = x;
	window_height= y;
	GLUI_Master.get_viewport_area(&subwindow_x, &subwindow_y, &subwindow_width, &subwindow_height);
	if(full_screen->get_int_val())
		aspectRatio = (float)window_width / (float)window_height;
	else
		aspectRatio = (float)subwindow_width / (float)subwindow_height;
	glutPostRedisplay();
}

// draw the scene
void myGlutDisplay(	void )
{
	// check for movement from the Wiimote
	CheckMovement();

	//clear the buffers
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	//re-set the light
	glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 100 / live_light_intensity_trans );

	//set up the viewport
	if(stereo_view->get_int_val()) {
		if(full_screen->get_int_val())
			glViewport(0, 0, window_width / 2, window_height);
		else
			glViewport(subwindow_x, 0, subwindow_width / 2, subwindow_height);
		SetProjection(stereo_t::STEREO_LEFT);
		SetCamera(stereo_t::STEREO_LEFT);
		DrawObject1();
		DrawObject2();
		DrawObject3();
		DrawFloor();
		DrawHand();

		if(full_screen->get_int_val())
			glViewport(window_width / 2, 0, window_width / 2, window_height);	
		else
			glViewport(subwindow_x + (subwindow_width / 2), 0, subwindow_width / 2, window_height);
		SetProjection(stereo_t::STEREO_RIGHT);
		SetCamera(stereo_t::STEREO_RIGHT);
		DrawObject1();
		DrawObject2();
		DrawObject3();
		DrawFloor();
		DrawHand();
	} else {
		if(full_screen->get_int_val())
			glViewport(0, 0, window_width, window_height);
		else
			glViewport(subwindow_x, subwindow_y, subwindow_width, subwindow_height);
		SetProjection(stereo_t::STEREO_NONE);
		SetCamera(stereo_t::STEREO_NONE);
		DrawObject1();
		DrawObject2();
		DrawObject3();
		DrawFloor();
		DrawHand();
	}
	glutSwapBuffers();
}
